﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ESP
{
    //////////////////////////////////////////////////////////////////////
//   Alan Oursland  
// 
//   ESP Java implementation.
//
//	 This code is a direct port of Faustino Gomez's ESP code
//   that was code started from Daniel Polani's translation of 
//   Dave Moriarty's original SANE code from C to C++.
//   
//   $Log: SimpleRecurrentNetwork.java,v $
//////////////////////////////////////////////////////////////////////////
    public class SimpleRecurrentNetwork : Network
    {
        public SimpleRecurrentNetwork(int inputCount, int neuronCount, int outputCount) :
            base(inputCount, neuronCount, outputCount)
        {
        }

/*	
	public SimpleRecurrentNetwork( SimpleRecurrentNetwork net ) {
		super( net );
	}
*/
/*	
	public void addNeuron() {
		addConnection( getTotalInputs()-1 );
		super.addNeuron();
	}
 
	public void removeNeuron(int sp) {
		removeConnection( getInputCount()+sp );
		super.removeNeuron(sp);
	}
*/
        private double[] tmp;

        public override void activate(double[] input, double[] output)
        {
            /* evaluate hidden/output layer */
            tmp = new double[getInputCount() + activation.Length];
            Array.Copy(input, 0, tmp, 0, getInputCount());
            Array.Copy(activation, 0, tmp, getInputCount(), activation.Length);

            //Array.Copy( activation, 0, input, getInputCount(), activation.Length );

            for (int i = 0; i < activation.Length; ++i)
            {
                /*for each hidden unit*/
                activation[i] = 0.0;
                if (!getNeuron(i).lesioned)
                {
                    for (int j = 0; j < getTotalInputs(); ++j)
                    {
                        activation[i] += getNeuron(i).weight[j]*tmp[j];

                    }
                    activation[i] = sigmoid(activation[i]);
                }
            }

            for (int i = 0; i < output.Length; ++i)
            {
                output[i] = 0.0;
                for (int j = 0; j < activation.Length; ++j)
                {
                    output[i] += activation[j]*getNeuron(j).weight[getTotalInputs() + i];
                }
                output[i] = sigmoid(output[i]);
            }
        }

        public override void save(String filename)
        {
            saveText(filename + "_SRN");
        }

        public override int getTotalInputs()
        {
            return getInputCount() + getNeuronCount();
        }

        public override int getGeneSize()
        {
            return getTotalInputs() + getOutputCount();
        }
    }
}
